package com.project.mq.mqserver.core;


import lombok.Data;

import java.io.Serializable;
import java.util.UUID;


/**
 * 表示一个要传递的消息
 * 注意!!! 此处的 Message 对象，是需要能够在网络上传输，并且也需要能写入到文件中。
 * 此时就需要针对 Message 进行序列化和反序列化。
 * 使用标准库自带的序列化/反序列化
 * 此处准备使用标准库自带的方式进行序列化反序列化，而不使用 json 方式。
 * json 本质上是文本格式（里面放的也是文本类型的数据），而此处的 Message，里面存储的是二进制数据。
 */
@Data
public class Message implements Serializable {
    private BasicProperties basicProperties = new BasicProperties();
    private byte[] body;

    //辅助属性
    //Message后续会存储很多消息(如果持久化的话)
    //一个文件中会存储很多消息,如何找到某个消息在文件中的具体位置呢
    // 消息在文件中对应的 offset 的范围，[offsetBeg, offsetEnd)
    // 从这个范围取出的 byte[] 正好可以反序列化成一个 Message 对象。
    // offsetBeg 前面的 4 个字节是消息的长度
    //这俩属性并不需要被序列化保存到文件中~~ 此时消息一旦被写入文件之后，所在的位置就固定了，并不需要单独存储。
    //这俩属性存在的目的，主要就是为了让内存中的 Message 对象，能够快速找到对应的硬盘上的 Message 的位置。
    private transient long offsetBeg = 0;//消息数据的开头距离文件的开头的位置偏移(字节)
    private transient long offsetEnd = 0;//消息数据的结尾距离文件的开头的位置偏移(字节)

    //针对文件中的消息,如果删除,使用的是逻辑删除的方法
    // 消息在文件中是否有效。0x0 表示无效，0x1 表示有效
    private byte isValid = 0x1;

    // 创建新的消息，同时给该消息分配一个新的 messageId
    // routingKey 以参数为准，会覆盖掉 basicProperties 中的 routingKey
    //万一routingKey和basicProperties里的routingKey冲突,以外面的为主
    public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body) {
        Message message = new Message();
        if (basicProperties != null) {
            //message.basicProperties = basicProperties;
            message.setBasicProperties(basicProperties);
        }
//        message.basicProperties.setMessageId("M-" + UUID.randomUUID().toString());
//        message.basicProperties.setRoutingKey(routingKey);
//        message.body = body;
        //此处生成的messageId以M-做前缀,
        message.setMessageId("M-" + UUID.randomUUID());
        message.setRoutingKey(routingKey);
        message.body = body;
        //此处是把 body 和 basicProperties 先设置出来。他俩是 Message 的核心内容。
        // 而 offsetBeg、offsetEnd、isValid，则是消息持久化的时候才会用到。
        // 在把消息写入文件之前再进行设定。此处只是在内存中创建一个 Message 对象。
        return message;
    }

    public String getMessageId() {
        return basicProperties.getMessageId();
    }

    public void setMessageId(String messageId) {
        basicProperties.setMessageId(messageId);
    }

    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }

    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }

    public int getDeliverMode() {
        return basicProperties.getDeliveryMode();
    }

    public void setDeliverMode(int mode) {
        basicProperties.setDeliveryMode(mode);
    }

    // 省略 getter setter
}